Skip to content

Test/improve code cov 2#963

Open
Saadha123 wants to merge 11 commits intowso2:mainfrom
Saadha123:test/improve-code-cov-2
Open

Test/improve code cov 2#963
Saadha123 wants to merge 11 commits intowso2:mainfrom
Saadha123:test/improve-code-cov-2

Conversation

@Saadha123
Copy link
Contributor

@Saadha123 Saadha123 commented Feb 6, 2026

Purpose

Improve unit test coverage across gateway-controller pkg directories to enhance code reliability and facilitate safer refactoring.

Goals

Increase unit test coverage to >80% for gateway-controller pkg directories.

Approach

Added targeted unit tests focusing on uncovered code paths:

  • constants: Validation tests for all constant values
    
  • policyxds: Server lifecycle tests (initialization, shutdown)
    
  • logger: Source path formatting tests with actual log output
    
  • metrics: Enable/disable flags, server lifecycle, and memory metrics updater tests
    
  • storage: Helper function tests for SQLite constraint error detection
    

User stories

Summary of user stories addressed by this change>

Documentation

Link(s) to product documentation that addresses the changes of this PR. If no doc impact, enter “N/A” plus brief explanation of why there’s no doc impact

Automation tests

  • Unit tests

    Code coverage information

  • Integration tests

    Details about the test cases and coverage

Security checks

Samples

Provide high-level details about the samples related to this feature

Related PRs

List any other related PRs

Test environment

List all JDK versions, operating systems, databases, and browser/versions on which this feature/fix was tested

Summary by CodeRabbit

  • Tests
    • Added comprehensive tests covering constants, logger formatting, metrics behavior, server lifecycle, SQLite storage operations, and API key management (creation, update, revocation, listing, expiration and edge cases) to improve reliability and prevent regressions.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 6, 2026

Warning

Rate limit exceeded

@Saadha123 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 0 minutes and 1 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

Walkthrough

Adds extensive unit tests across multiple packages (constants, logger, metrics, policyxds, storage, utils) without modifying production code; introduces many new test functions, mocks, and helpers to increase coverage and exercise server, storage, metrics, and API key logic.

Changes

Cohort / File(s) Summary
Constants & Logger tests
gateway/gateway-controller/pkg/constants/constants_test.go, gateway/gateway-controller/pkg/logger/logger_test.go
Adds tests validating constant values (XDS, TLS, ALPN, ports, schemes, localhost) and logger formatting behavior across JSON, text, and uppercase formats.
Metrics tests
gateway/gateway-controller/pkg/metrics/metrics_test.go
Adds tests for metrics enablement, SetEnabled, server creation/start/stop, and the memory metrics updater lifecycle with cancellation and error handling.
Policy XDS server tests
gateway/gateway-controller/pkg/policyxds/server_test.go
Adds server initialization tests that assemble policy, API key, and lazy resource stores and verify server construction and Stop() behavior.
SQLite storage tests
gateway/gateway-controller/pkg/storage/sqlite_test.go
Large suite of tests (~25+) covering CRUD and error paths for Config, LLMProviderTemplate, Certificate, APIKey entities, listing, retrieval by identifiers, load-from-database flows, and Close idempotency.
API key management tests
gateway/gateway-controller/pkg/utils/api_key_test.go
Extensive test scaffolding with mock storage/XDS manager and helpers covering API key creation, revocation, update, regeneration, listing, expiration units, permission checks, and database conflict/retry scenarios.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🐰 I hopped through code and stitched each test with care,

Constants, logs, and storage found their places there.
Metrics hum softly, servers bow and stop,
Keys and certs parade — not a single flop!
A little rabbit cheers: "More coverage — hip-hop!" 🥕

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 38.71% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Test/improve code cov 2' is vague and uses a non-descriptive abbreviation ('cov') that doesn't clearly convey the purpose of adding comprehensive unit tests across multiple packages. Use a more descriptive title like 'Add comprehensive unit tests for gateway-controller packages' to clearly communicate the main objective of improving code coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Description check ✅ Passed The description adequately covers Purpose, Goals, and Approach sections with specific details about test additions across five packages, but contains multiple unfilled template placeholders without substantive content.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Fix all issues with AI agents
In `@gateway/gateway-controller/pkg/utils/api_key_test.go`:
- Around line 1829-1872: The test shows ListAPIKeys panics when
ListAPIKeyParams.User is nil because filterAPIKeysByUser dereferences the user;
update the ListAPIKeys function to validate params.User (or return a clear
error) before calling filterAPIKeysByUser, and modify filterAPIKeysByUser to
defensively handle a nil user (return an error instead of panicking); add/adjust
unit tests to assert an error is returned for a nil User rather than relying on
defer/recover.
- Around line 1639-1681: The test "regenerate - database conflict with retry"
currently never triggers a conflict because mockDB.returnConflict is false and
callCount is unused; update the mock behavior so mockDB.UpdateAPIKey returns a
conflict on the first call and succeeds on the second (use callCount to track
invocations), e.g., initialize callCount := 0, set mockDB.returnConflict = true
or mockDB.updateError to a conflict on first call, then in the mock UpdateAPIKey
implementation increment callCount and clear the conflict (set
returnConflict=false or updateError=nil) after the first failure to simulate
retry; keep the test parameters and assertions the same and ensure you reference
NewAPIKeyService and service.RegenerateAPIKey (APIKeyRegenerationParams) to
validate the retry path.
- Around line 1150-1186: The test TestCreateAPIKey_ConfigStoreRollback currently
guards assertions with "if err == nil { ... }" which masks failures; update the
test to assert the expected outcome directly by replacing the conditional with
explicit assertions: call assert.NoError(t, err) (or assert.Error if the
intended behavior is failure) immediately after invoking
service.CreateAPIKey(params), then assert.NotNil(t, result) and any
rollback-related expectations; reference the test function
TestCreateAPIKey_ConfigStoreRollback and the CreateAPIKey call on the service
along with APIKeyCreationParams to locate and update the assertions.
- Around line 1801-1825: The test currently discards the result of
service.ListAPIKeys (line with `_ = err`) so it never asserts behavior; change
it to capture the returned values from ListAPIKeys and add assertions: call res,
err := service.ListAPIKeys(params) and then assert either err != nil (verify it
indicates the database failure from mockDB.getError or at least non-nil) OR if
err == nil assert that res is an empty slice (len(res) == 0). Update the test
named "list fails when both memory and database fail" to use these checks
against the ListAPIKeys return values so the test can fail on unexpected
behavior.
🧹 Nitpick comments (4)
gateway/gateway-controller/pkg/logger/logger_test.go (1)

162-198: Coverage-only test with no output assertions.

The test acknowledges it can't capture os.Stdout output, so it only exercises code paths without verifying correctness of the ReplaceAttr callback. This is fine for coverage, but consider injecting a bytes.Buffer (similar to TestXDSLogger) by refactoring NewLogger to accept an io.Writer, which would allow asserting formatted source paths. This would make the test actually validate behavior.

gateway/gateway-controller/pkg/metrics/metrics_test.go (2)

292-313: TestServer_Start silently swallows errors — test can never fail.

Both Start() (line 306) and Stop() (line 312) errors are ignored. With port 0, Start should reliably succeed, so consider asserting assert.NoError on it. Also, Stop error on line 312 is discarded.

Suggested fix
 	err := server.Start()
-	if err != nil {
-		t.Logf("Start returned error (may be acceptable): %v", err)
-	}
+	if err == nil {
+		// Clean up only if Start succeeded
+		ctx := context.Background()
+		stopErr := server.Stop(ctx)
+		if stopErr != nil {
+			t.Logf("Stop returned error: %v", stopErr)
+		}
+	} else {
+		t.Logf("Start returned error (may be acceptable): %v", err)
+	}
-
-	// Clean up
-	ctx := context.Background()
-	server.Stop(ctx)

269-290: TestStartMemoryMetricsUpdater relies on time.Sleep for synchronization.

The test sleeps 250ms to let the goroutine run, then 50ms for cleanup. While this is unlikely to be flaky in practice (the goroutine responds to context cancellation), note that these tests won't detect panics inside the goroutine since they'd crash a different goroutine than the test's.

gateway/gateway-controller/pkg/storage/sqlite_test.go (1)

36-40: Package-level mutable counters are not safe for parallel test execution.

configCounter, llmTemplateCounter, and apiKeyCounter are incremented by createTest* helpers without synchronization. Currently safe since no test uses t.Parallel(), but if parallelism is ever added, these will race. Consider using atomic.AddInt32 or passing a *testing.T-scoped counter.

Comment on lines +1829 to +1872
func TestListAPIKeys_FilterError(t *testing.T) {
logger := slog.New(slog.NewTextHandler(io.Discard, nil))

t.Run("list with nil user causes panic (code should validate user first)", func(t *testing.T) {
store := storage.NewConfigStore()

testConfig := createTestAPIConfig("api-1", "test-api")
_ = store.Add(testConfig)

// Add a key so we get past the memory store
key := &models.APIKey{
ID: "key-1",
Name: "test-key",
APIKey: "hashed-key",
APIId: "api-1",
Status: models.APIKeyStatusActive,
CreatedBy: "user1",
}
_ = store.StoreAPIKey(key)

service := NewAPIKeyService(store, nil, nil, &config.APIKeyConfig{
APIKeysPerUserPerAPI: 10,
Algorithm: constants.HashingAlgorithmSHA256,
})

params := ListAPIKeyParams{
Handle: "test-api",
User: nil, // This will cause a panic in filterAPIKeysByUser when logging
CorrelationID: "corr-123",
Logger: logger,
}

// The code has a bug: it panics when user is nil
// This test documents that behavior (ideally the code should be fixed to validate user first)
defer func() {
if r := recover(); r != nil {
// Expected: panic due to nil user access after filterAPIKeysByUser returns error
assert.NotNil(t, r)
}
}()

_, _ = service.ListAPIKeys(params)
})
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Test documents a nil-user panic bug — consider filing an issue to fix the root cause.

The test explicitly documents that ListAPIKeys panics when User is nil (line 1861), catching it with defer/recover. While documenting known defects in tests is reasonable, the production code should ideally validate User before dereferencing. If this is a known issue, consider opening an issue to track the fix.

Do you want me to open a new issue to track the nil-user validation fix in ListAPIKeys?

🤖 Prompt for AI Agents
In `@gateway/gateway-controller/pkg/utils/api_key_test.go` around lines 1829 -
1872, The test shows ListAPIKeys panics when ListAPIKeyParams.User is nil
because filterAPIKeysByUser dereferences the user; update the ListAPIKeys
function to validate params.User (or return a clear error) before calling
filterAPIKeysByUser, and modify filterAPIKeysByUser to defensively handle a nil
user (return an error instead of panicking); add/adjust unit tests to assert an
error is returned for a nil User rather than relying on defer/recover.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@gateway/gateway-controller/pkg/utils/api_key_test.go`:
- Around line 2195-2209: Rename the misnamed sub-test to match its assertion and
behavior: change the t.Run name string in the test that constructs store :=
storage.NewConfigStore() and service := NewAPIKeyService(...) so it no longer
says "no db and memory store error returns error" and instead reads something
like "no db falls back to memory count of zero and passes" (also update the
inline comment near the enforceAPIKeyLimit invocation to reflect that memory
returns 0 and the test expects no error).
- Around line 1150-1184: The test TestCreateAPIKey_ConfigStoreRollback is
misnamed because it creates a normal storage.NewConfigStore and never triggers
ConfigStore.StoreAPIKey failure; either rename the sub-test to reflect a
successful creation or modify the setup to provoke a real ConfigStore error so
rollback is exercised — for example replace storage.NewConfigStore with a mock
that implements StoreAPIKey and returns an error, or adjust APIKeyCreationParams
to hit validation that causes ConfigStore.StoreAPIKey to fail, then assert that
CreateAPIKey on the APIKeyService rolls back the DB by checking mockDB
interactions; update the sub-test name and assertions accordingly to match the
chosen approach.
🧹 Nitpick comments (1)
gateway/gateway-controller/pkg/utils/api_key_test.go (1)

958-967: UpdateAPIKey mock lacks a conflictOnceOnUpdate mechanism (unlike SaveAPIKey).

SaveAPIKey has conflictOnceOnSave to simulate a conflict that resolves on retry, but UpdateAPIKey has no equivalent. This is why the "regenerate - database conflict with retry" test at Line 1637 can't actually exercise the retry path. Adding a parallel conflictOnceOnUpdate field would enable a proper retry test.

Suggested addition
 type mockStorage struct {
 	...
 	conflictOnceOnSave bool
 	saveCallCount      int
+	conflictOnceOnUpdate bool
+	updateCallCount      int
 }

 func (m *mockStorage) UpdateAPIKey(apiKey *models.APIKey) error {
+	m.updateCallCount++
+	if m.conflictOnceOnUpdate && m.updateCallCount == 1 {
+		return storage.ErrConflict
+	}
 	if m.returnConflict {
 		return storage.ErrConflict
 	}
 	if m.updateError != nil {
 		return m.updateError
 	}
 	m.apiKeys[apiKey.ID] = apiKey
 	return nil
 }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant